<template>
  <div ref="chart" :style="{ width: width, height: height }" class="pie-chart"></div>
</template>

<script>
import * as echarts from 'echarts'
import resize from '@/views/dashboard/mixins/resize'

require('echarts/theme/macarons')

export default {
  name: 'PieChart',
  mixins: [resize],
  props: {
    // chartDOM宽度
    width: {
      type: String,
      default: '100%',
    },
    // chartDOM高度
    height: {
      type: String,
      default: '320px',
    },
    // 配置
    // 该参数用于跟默认配置做递归树合并，得到新的默认配置
    option: {
      type: Object,
      default: function () {
        return {}
      },
    },
    seriesData: {
      // 需要显示的数据
      type: Array,
      default: function () {
        return []
      },
    },
  },
  data() {
    return {
      chart: null, // chart实例
      // 默认serie配置
      defSerie: {
        // barMinWidth: 8,
        // barMaxWidth: 32,
        // data: [],
        itemStyle: {
          normal: {
            barBorderRadius: 16,
            shadowColor: '#eeeeee',
            shadowBlur: 1,
          },
        },
        // 文本标签
        label: {
          normal: {
            show: true,
            // 文本内容格式化
            //     可以是模板字符串{'{a}': 系列名, '{b}': 数据名, '{c}': 数据值, {d}': 百分比}
            //     可以是function
            //         {<text_mapContent>|<text_content>}
            //         上面的写法，可以配合rich做到更深的自定义，左边的字符串映射右边的文本内容
            formatter: function (params) {
              return `{x${params.dataIndex}|${params.percent}%}`
            },
            // 富文本样式
            //     接收一个Object，可以用function返回，但经过测试，function不能写在这里，得写在外面
          },
        },
        minAngle: 10, // 最小圆心角度
        name: '',
        roseType: false, // 是否南丁格尔图{true: 默认圆心角不等, 'radius': 默认圆心角不等, 'area': 默认圆心角相等}
        type: 'pie',
      },
    }
  },
  computed: {
    comp_option() {
      let obj = {
        backgroundColor: '#ffffff',
        color: ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'],
        // color: ['#d223e7', '#4962FC', '#18D070', '#3F77FE', '#12ED93', '#02CBF9', '#3FD0F9', '#f376e0', '#4962FC', '#189CBF', '#768BFF', '#01C2F9'],
        // color: ['#FFDCDF', '#FFBCC2', '#FFA7AF', '#FF7F8A', '#FF4A5A', '#EB0A1E'],
        grid: {
          top: 40,
          bottom: 64,
        },
        // 图例
        legend: {
          top: 'middle',
          right: '10%',
          icon: 'circle', // 图例形状{'roundRect': 默认圆角矩形, 'circle': 圆形}
          orient: 'vertical',
          itemHeight: 16, // 图例高
          itemWidth: 16, // 图例宽
          // 图例文本样式
          textStyle: {
            fontSize: 14,
          },
          type: 'scroll', // 类型{'plain': 普通, 'scroll': 可滚动}
        },
        // 图形系列数据
        series: [
          // 测试用的数据 start --------------------
          // {
          //     ...this.defSerie,
          //     id: 'series0',
          //     data: [
          //         { name: '房产类', value: 622 },
          //         { name: '土地使用权类', value: 2271 },
          //         { name: '在建工程类', value: 3622 },
          //         { name: '生产设备类', value: 388 },
          //         { name: '广告位类', value: 421 },
          //         { name: '其它类', value: 69 },
          //     ],
          //     name: 'series0_name',
          // },
          // 测试用的数据 end --------------------
        ],
        // 悬浮文本框
        tooltip: {
          formatter: params => {
            // console.log(params)
            const {marker, data, value} = params
            const name = data?.label || data.name
            return marker + name + ': ' + value
          },
        },
      }

      this.mergeOption(obj, this.option)
      return obj
    },
  },
  watch: {
    seriesData: {
      deep: true,
      handler(val) {
        this.init()
        this.setOption(val)
      },
    },
  },
  mounted() {
    this.chart = echarts.init(this.$refs.chart)
    this.init()
    this.setOption(this.seriesData)
    this.chart.on('click', params => {
      this.$emit('clicked', params)
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    /**
     * @description: 初始化
     * @param {Funtion} beforeFn 初始化前的函数
     */
    init(beforeFn = function () {
    }) {
      let finalOption = beforeFn.call(this, JSON.parse(JSON.stringify(this.comp_option)), {...this.defSerie}) || this.comp_option

      this.chart.setOption(finalOption, true)
    },
    setOption(data) {
      if (!data) return
      this.chart.setOption({
        series: data,
      })
    },
    /**
     * @description: 合并配置
     * @param {*} defOption 默认配置
     * @param {*} newOption 新配置
     */
    mergeOption(defOption, newOption) {
      for (const [k, v] of Object.entries(newOption)) {
        if (Reflect.has(defOption, k)) {
          let type = Object.prototype.toString.call(v)
          type = type.split(' ')[1].split(']')[0]
          switch (type) {
            case 'Object':
              let defType = Object.prototype.toString.call(defOption[k])
              defType = defType.split(' ')[1].split(']')[0]
              if (defType === 'Object') {
                this.mergeOption(defOption[k], v)
              } else {
                defOption[k] = v
              }
              break
            default:
              defOption[k] = v
              break
          }
        } else {
          defOption[k] = v
        }
      }
    },
  },
}
</script>

<style lang="scss" scoped></style>
